<?php

/*邀请活动*/

namespace App\Http\Controllers\AgentAdmin;

use App\Enums\AvailableStatus;
use App\Exports\InviteActivityExport;
use App\Exports\InvitedUsersExport;
use App\Http\Controllers\Controller;
use App\Jobs\DownloadsJob;
use App\Models\AgentUser;
use App\Models\Download;
use App\Models\InvitationActivity;
use App\Models\InvitationRegister;
use Carbon\Carbon;
use Vinlon\Laravel\LayAdmin\Exceptions\AdminException;
use Vinlon\Laravel\LayAdmin\PaginateResponse;

class InvitationActivityController extends Controller
{
    /*邀请活动列表*/
    public function listInvites()
    {
        /** @var AgentUser $user */
        $user = auth()->user();
        $query = InvitationActivity::query()
            ->where('agent_id', $user->agent_id)
            ->when(request()->keyword, function ($q) {
                $likeVal = '%' . request()->keyword . '%';

                return $q->where('name', 'like', $likeVal);
            })
            ->orderByDesc('id');

        return paginate_result($query, function (InvitationActivity $activity) {
            $activity->ongoing_status = $activity->getOnGoingStatus();
            $activity->invited_count = $activity->registers()->sum('register_count');
            $activity->invited_real_count = $activity->registers()->sum('realname_count');

            return $activity;
        });
    }

    /*创建邀请活动*/
    public function createInvites()
    {
        request()->validate([
            'name' => 'required',
            'start_date' => 'required',
            'end_date' => 'required',
            'ranking_num' => 'required',
            'enable_consume' => 'required',
            'img_url' => 'required',
            'id' => 'nullable',
        ]);

        /** @var AgentUser $user */
        $user = auth()->user();

        /** @var InvitationActivity $activity */
        $activity = get_entity(InvitationActivity::class);
        $activity->agent_id = $user->agent_id;
        $activity->name = request()->name;
        $activity->ranking_num = request()->ranking_num;
        if (!request()->get('id')) {
            $activity->enable_consume = request()->enable_consume;
        }
        $activity->img_url = request()->img_url;

        $startTime = Carbon::parse(request()->start_date)->startOfDay();
        $endTime = Carbon::parse(request()->end_date)->endOfDay();

        if ($startTime->gt($endTime)) {
            throw new AdminException('开始日期必须早于结束日期');
        }
        if ($startTime->notEqualTo($activity->start_time)) {
            if ($startTime->lt(now()->startOfDay())) {
                throw new AdminException('开始日期不能早于当前日期');
            }
        }
        if ($endTime->notEqualTo($activity->end_time)) {
            if ($endTime->lt(now()->endOfDay())) {
                throw new AdminException('活动结束日期不能晚于当前日期');
            }
        }

        $activity->start_time = $startTime;
        $activity->end_time = $endTime;
        $activity->status = AvailableStatus::ENABLED;

        $this->checkActivityTime($activity);
        $activity->save();
    }

    /*获取单条活动详情*/
    public function getInvitesDetail($id)
    {
        return InvitationActivity::query()->find($id);
    }

    /*删除活动*/
    public function deleteInvitesDetail($id)
    {
        return InvitationActivity::query()->find($id)->delete();
    }

    /*邀请活动-邀请详情*/
    public function getInvitesDetails()
    {
        $page = request()->page ?: 1;
        $limit = request()->limit ?: 10;

        $query = InvitationRegister::query()
            ->with(['auth', 'user'])
            ->where('activity_id', request()->id)
            ->when(request()->keyword, function ($q) {
                return $q->whereHas('user', function ($q2) {
                    $likeVal = '%' . request()->keyword . '%';

                    return $q2->where('nickname', 'like', $likeVal)->orWhere('mobile', 'like', $likeVal);
                });
            })
            ->orderByDesc('realname_count');

        $count = $query->count();
        $invite = $query->offset(($page - 1) * $limit)->limit($limit)->get()->toArray();

        foreach ($invite as $key => $item) {
            $invite[$key]['ranking_num'] = $key + 1;
        }

        return new PaginateResponse($count, $invite);
    }

    /*不允许参与活动*/
    public function changeInvitesStatusNo()
    {
        return InvitationRegister::query()->where('id', request()->id)->update(['is_allowed' => AvailableStatus::DISABLED]);
    }

    /*允许参与活动*/
    public function changeInvitesStatusYes()
    {
        return InvitationRegister::query()->where('id', request()->id)->update(['is_allowed' => AvailableStatus::ENABLED]);
    }

    /*禁用该活动*/
    public function changeActivityStatusClose()
    {
        return InvitationActivity::query()->where('id', request()->id)->update(['status' => AvailableStatus::DISABLED]);
    }

    /*启用该活动*/
    public function changeActivityStatusOpen()
    {
        return InvitationActivity::query()->where('id', request()->id)->update(['status' => AvailableStatus::ENABLED]);
    }

    /*导出排行榜单*/
    public function exportRegisters($activityId)
    {
        $activity = InvitationActivity::query()->find($activityId);
        $registers = InvitationRegister::query()
            ->with(['auth', 'user'])
            ->where('activity_id', $activityId)
            ->orderByDesc('realname_count')
            ->get();

        foreach ($registers as $index => &$register) {
            $register['ranking_num'] = $index + 1;
        }

        return new InviteActivityExport($activity->name, $registers->toArray());
    }

    /*导出邀请数据*/
    public function exportInvitedUsers($activityId, $registerId)
    {
        $activity = InvitationActivity::query()->find($activityId);
        $register = InvitationRegister::query()->find($registerId);

        $file = sprintf('%s_%s_邀请用户列表_%s.xlsx', $activity->name, $register->user->mobile, now()->format('YmdHis'));

        $user = auth()->user();

        $request = request()->all();
        $request['activityId'] = $activityId;
        $request['registerId'] = $registerId;

        $download = Download::create([
            'agent_id' => $user->agent_id,
            'user_id' => $user->id,
            'name' => $file,
            'url' => 'storage/' . $file,
            'status' => 0,
            'model' => InvitedUsersExport::class,
            'request' => json_encode($request),
        ]);

        dispatch(new DownloadsJob($download));
    }

    /** 检查活动时间是否存在重叠 */
    private function checkActivityTime(InvitationActivity $activity)
    {
        $existCount = InvitationActivity::query()
            ->where('agent_id', $activity->agent_id)
            ->where('start_time', '<=', $activity->end_time)
            ->where('end_time', '>=', $activity->start_time)
            ->when($activity->id, function ($q) use ($activity) {
                return $q->where('id', '!=', $activity->id);
            })->count();
        if ($existCount) {
            throw new AdminException('当前时间段已经存在活动');
        }
    }
}
